package org.operator.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Map;
import javax.sql.DataSource;

import org.operator.conn.conf.ConfigDbConfig;

public class D {
	
	private static DataSource dataSource;
	private static String version="V1.4.4_12";
	private static String TablePrefix="";
	private static String pk="id";
	private static boolean isPkAutoInc=true;
	private static boolean isAutoClose=true;
	private static boolean checkField=true;
	
	
	private static final ThreadLocal<Connection> threadConn = new ThreadLocal<Connection>(){
		//ThreadLocal没有被当前线程赋值时或当前线程刚调用remove方法后调用get方法，返回此方法值
        @Override
        protected Connection initialValue()
        {
            return null;
        }
    };
	
	
	public static M M(){
		return new M();
	}

	public static M M(String table) {
		return new M(table);
	}
	
	public static M M(Object bean) {
		return new M(bean);
	}
	
	public static M M(Class<?> beanClass) {
		return new M(beanClass);
	}
	
	public static Connection getConnection() {
		try {
			
			Connection conn=threadConn.get();
	//		System.out.println("Thread:"+Thread.currentThread().getName()+",conn==null:"+(conn==null));
			if(null!=conn) {
				return conn;
			}else if(null!=dataSource) {
				conn = dataSource.getConnection();
			}else {
				
				Map<String, String> conf = ConfigDbConfig.getInstance("db").getDbConf();
				
				Class.forName(conf.get("driver"));
				
				conn = DriverManager.getConnection(conf.get("url"), conf.get("username"), conf.get("password"));;
			}
			threadConn.set(conn);
			return conn;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 获取事务连接
	 * @return Connection 返回事务连接
	 * @throws SQLException 获取失败或设置为事务失败时关闭连接并抛异常
	 */
	public static Connection getTransConnection() {
		Connection conn=null;
		try {
			conn= getConnection();
			conn.setAutoCommit(false);
		} catch (Exception e) {
			closeConn(conn);
			e.printStackTrace();
			return null;
		}
		return conn;
	}
	
	/**
	 * 事务提交
	 * 中途异常关闭conn连接
	 * @param conn 事务连接
	 * @throws SQLException if has error
	 */
	public static void commit(Connection conn) throws SQLException{
		SQLException ex = null;
		try {
			conn.commit();
		} catch (SQLException e) {
			ex=e;
		}finally {
			autoCloseTransConn(conn);
			if(null!=ex) {
				throw ex;
			}
		}
	}
	
	/**
	 * 事务回滚，中途异常关闭conn连接
	 * @param conn 事务连接
	 * @throws SQLException if has error
	 */
	public static void rollback(Connection conn) throws SQLException{
		SQLException ex = null;
		try {
			conn.rollback();
		} catch (SQLException e) {
			ex=e;
		}finally {
			autoCloseTransConn(conn);
			if(null!=ex) {
				throw ex;
			}
		}
	}
	
	/**
	 * 关闭连接,有事务不关闭
	 * @throws SQLException
	 */
	public static void closeConn(){
		Connection conn=threadConn.get();
		try {
			if(conn!=null && !conn.isClosed()) {
				conn.close();
				threadConn.remove();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 关闭连接,有事务不关闭
	 * @param conn
	 * @throws SQLException
	 */
	protected static void closeConn(Connection conn) {
		try {
			if(conn!=null && !conn.isClosed()) {
				conn.close();
				threadConn.remove();
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 关闭连接,有事务不关闭
	 * @param conn
	 * @throws SQLException
	 */
	protected static void autoCloseConn(Connection conn) throws SQLException{
		if(D.isAutoClose() && conn.getAutoCommit()) {
			D.closeConn(conn);
		}
	}
	
	/**
	 * 关闭事务连接
	 * @param conn
	 * @throws SQLException
	 */
	protected static void autoCloseTransConn(Connection conn) throws SQLException{
		if(D.isAutoClose()) {
			D.closeConn(conn);
		}
	}
	
//	public static void setDbConfig(String DbUrl,String DbUser,String DbPassword) throws ClassNotFoundException{
//		setDbConfig(new DbConfig(DbUrl,DbUser,DbPassword));
//	}
//	
//	public static void setDbConfig(DbConfig dbConfig) throws ClassNotFoundException{
//		D.dbConfig = dbConfig;
//		Class.forName(dbConfig.getDriverName());
//	}
//	
//	public static DbConfig getDbConfig() {
//		return dbConfig;
//	}
	
	public static void setDataSource(DataSource dataSource) {
		D.dataSource=dataSource;
	}
	
	public static DataSource getDataSource() {
		return dataSource;
	}
	
	public static String getTablePrefix() {
		return TablePrefix;
	}

	public static void setTablePrefix(String tablePrefix) {
		TablePrefix = tablePrefix;
	}
	
	public static boolean isAutoClose() {
		return isAutoClose;
	}

	public static void setAutoClose(boolean isAutoClose) {
		D.isAutoClose = isAutoClose;
	}

	public static boolean isCheckField() {
		return checkField;
	}

	public static void setCheckField(boolean checkField) {
		D.checkField = checkField;
	}

	public static String getPk() {
		return pk;
	}

	public static void setPk(String pk) {
		D.pk = pk;
	}

	public static boolean isPkAutoInc() {
		return isPkAutoInc;
	}

	public static void setPkAutoInc(boolean isPkAutoInc) {
		D.isPkAutoInc = isPkAutoInc;
	}

	public static String getVersion(){
		return version;
	}
	
	public static void about() {
		String about="ThinkJDBC "+version+" By Leytton 2018/04/14-. Apache 2.0 Licence";
		System.out.println(about);
	}
	
}
